package cn.itsource.order.service.impl;

import cn.itsource.basic.contants.PayConstants;
import cn.itsource.basic.domain.Point;
import cn.itsource.basic.service.impl.BasicServiceImpl;
import cn.itsource.basic.util.AliPayUtil;
import cn.itsource.basic.util.CodeGenerateUtils;
import cn.itsource.basic.util.DistanceUtil;
import cn.itsource.order.domain.OrderAddress;
import cn.itsource.order.domain.ProductOrder;
import cn.itsource.order.domain.ProductOrderDetail;
import cn.itsource.order.mapper.OrderAddressMapper;
import cn.itsource.order.mapper.ProductOrderDetailMapper;
import cn.itsource.order.mapper.ProductOrderMapper;
import cn.itsource.order.service.IOrderAddressService;
import cn.itsource.order.service.IProductOrderService;
import cn.itsource.org.domain.Shop;
import cn.itsource.org.mapper.ShopMapper;
import cn.itsource.pay.domain.PayBill;
import cn.itsource.pay.mapper.PayBillMapper;
import cn.itsource.pay.service.IPayBillService;
import cn.itsource.product.domain.Product;
import cn.itsource.product.mapper.ProductMapper;
import cn.itsource.product.service.IProductService;
import cn.itsource.quartz.domain.QuartzJobInfo;
import cn.itsource.quartz.service.IQuartZService;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.UserAddress;
import cn.itsource.user.mapper.UserAddressMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class ProductOrderServiceImpl extends BasicServiceImpl<ProductOrder> implements IProductOrderService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private ProductOrderMapper productOrderMapper;
    @Autowired
    private ProductOrderDetailMapper productOrderDetailMapper;

    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private PayBillMapper payBillMapper;

    @Autowired
    private IPayBillService payBillService;

    @Autowired
    private IQuartZService quartZService;

    //{productId=8, addressId=1, payWay=AliPay}
    /*
        实现的步骤分析：
            1.获取当前的系统登录用户
            2.根据服务【productId】 查询用户购买的Product
            3.根据addressId 查询用户选择的地址
            4.组装OrderProduct 对象  --->根据用户选择的地址【UserAddress】 计算最近的门店
            5.组装OrderProductDetail对象 ---》根据【Product】  和一条订单关联【OrderProduct】
            6.组装OrderAddress对象  -->根据【UserAddress】 和一条订单关联【OrderProduct】
     */

    @Override
    @Transactional
    public String createOrder(Map<String, String> map, User user) {
        // map{productId=8, addressId=1, payWay=1}
        //产品的id
        Long productId = Long.valueOf(map.get("productId"));
        //用户上门地址
        Long addressId = Long.valueOf(map.get("addressId"));
        Long payWay = Long.valueOf(map.get("payWay"));

        //获取用户购买的产品
        Product product = productMapper.loadById(productId);
        //获取用户上门地址
        UserAddress userAddress = userAddressMapper.loadById(addressId);
        //组装OrderProduct 对象  --->根据用户选择的地址【UserAddress】 计算最近的门店
        ProductOrder productOrder = createProductOrder(product, user, userAddress);
        //保存 ProductOrder对象
        productOrderMapper.save(productOrder);

        //5.组装OrderProductDetail对象 ---》根据【Product】  和一条订单关联【OrderProduct】
        ProductOrderDetail productOrderDetail = productToProductOrderDetail(product);
        //设置与订单关联
        productOrderDetail.setOrder(productOrder);
        //保存 订单详细
        productOrderDetailMapper.save(productOrderDetail);
        // 6.组装OrderAddress对象  -->根据【UserAddress】 和一条订单关联【OrderProduct】
        OrderAddress orderAddress = userAddressToOrderAddress(userAddress);
        //设置关联信息
        orderAddress.setOrder(productOrder);
        orderAddress.setOrderSn(productOrder.getOrderSn());
        orderAddressMapper.save(orderAddress);
        //7.创建支付单
        PayBill payBill = createPayBill(productOrder);
        payBill.setUser_id(user.getId());//关联用户对象
        payBill.setPayChannel(payWay);//支付方式
        payBillMapper.save(payBill);
        //8.调用渠道接口支付
        /*
            1.导包
            2.关于支付的一些配置  AliPayConfig
            3.参考文档，支付请求移植
         */
        String result = payBillService.goPay(payBill);
        //添加定时任务
        QuartzJobInfo info = new QuartzJobInfo();//用来封装 定时器所需要的参数
        info.setJobName(productOrder.getOrderSn());
        Map<String,Object> pmap = new HashMap<>();
        pmap.put("orderSn", productOrder.getOrderSn());
        //参数
        info.setParams(pmap);//要传递的参数
        //设置时间  触发时间
        info.setFireDate(productOrder.getLastPayTime());
        quartZService.addJob(info);
        return result;

    }
    private PayBill createPayBill( ProductOrder productOrder){
        PayBill payBill = new PayBill();
        payBill.setDigest(productOrder.getDigest());
        payBill.setMoney(productOrder.getPrice());
        payBill.setState(0);
        payBill.setLastPayTime(productOrder.getLastPayTime());
        payBill.setBusinessType(PayConstants.BUSINESSTYPE_PRODUCT);//主要是确定哪一张表
        payBill.setBusinessKey(productOrder.getId());
        payBill.setCreateTime(new Date());
        payBill.setOrderSn(productOrder.getOrderSn());
        payBill.setShop_id(productOrder.getShop().getId());

        /*
            private Long payChannel; //0 余额 1 支付宝 2 微信 3 银联
         */


        return  payBill;
    }

    private OrderAddress userAddressToOrderAddress(UserAddress userAddress){
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress, orderAddress);
        return orderAddress;
    }

    private ProductOrderDetail productToProductOrderDetail(Product product){
        ProductOrderDetail productOrderDetail = new ProductOrderDetail();
        productOrderDetail.setProduct(product);
        productOrderDetail.setSaleCount(product.getSalecount()+1);
        productOrderDetail.setCreateTime(new Date());
        return productOrderDetail;
    }

    private ProductOrder createProductOrder(Product product,User user,UserAddress userAddress){
        //组装OrderProduct 对象  --->根据用户选择的地址【UserAddress】 计算最近的门店
        ProductOrder productOrder = new ProductOrder();
        productOrder.setDigest("[服务订单]"+product.getName());
        productOrder.setPrice(product.getSaleprice());
        productOrder.setLastPayTime(new Date(System.currentTimeMillis()+1000*60*2));
        productOrder.setUser(user);
        //计算最近的门店
        Point point = DistanceUtil.getPoint(userAddress.getFullAddress());
        //传入所有的门店 计算最近门店
        Shop shop = DistanceUtil.getNearestShop(point, shopMapper.loadAll());
        productOrder.setShop(shop);
        productOrder.setState(0);//待支付0
        //订单编号
        productOrder.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        productOrder.setProduct(product);
        return  productOrder;
    }
}
